<?php

namespace app\common\model;

use app\common\service\MailSer;
use app\common\service\MakeImage;
use app\common\service\third\WechatJS;
use app\common\service\third\WechatOpen;
use app\common\service\WechatMin;
use app\common\service\WxMin;
use app\common\validate\UserValidate;
use think\facade\Db;
use think\Model;
use think\model\concern\SoftDelete;
use think\Paginator;

class UserModel extends BaseModel
{
    use SoftDelete;

    //邀请者用户模型
    /**
     * @var self
     * */
    protected static $req_user_model;

    protected $table = "users";

    const DEFAULT_LEVEL = 3;

    public static $fields_sex = [
        ['name' => '未知'],
        ['name' => '男'],
        ['name' => '女'],
    ];

    //table列问题处理
    public static $fields_type_table_col = [
        ['name' => '角色名', 'key' => 'name', 'input' => ''],
        ['name' => '奖励能量值', 'key' => 'integral', 'input' => 'number'],
        ['name' => '购买金额', 'key' => 'money', 'input' => 'number'],
        ['name' => '优惠比例', 'key' => 'per', 'input' => 'number'],
        ['name' => '说明', 'key' => 'intro', 'input' => 'textarea'],
    ];

    public static $fields_type_cache_str = "user_type_json";
    public static $fields_type = [
        ['name' => '普通会员', 'value' => 0, 'integral' => '', 'money' => '', 'per' => '', 'intro' => ''],
        ['name' => '白银会员', 'value' => 1, 'integral' => '', 'money' => '', 'per' => '', 'intro' => ''],
        ['name' => '黄金会员', 'value' => 2, 'integral' => '', 'money' => '', 'per' => '', 'intro' => ''],
        ['name' => '黑金会员', 'value' => 3, 'integral' => '', 'money' => '', 'per' => '', 'intro' => ''],
    ];

    public function reqImage()
    {
        $images = MakeImage::makeReqCodeFile($this['id'], $this['req_code']);
        return empty($images) ? '' : $images[0];
    }

    public function getTypeNameAttr()
    {
        $vip_state = $this->user_model['vip_state'];
        return empty($vip_state) ? '普通会员' : 'vip会员';
    }

    public function setPasswordAttr($value)
    {
        $salt = rand(1000,9999);
        $this->setAttr('salt',$salt);
        return self::generatePwd($value,$salt);
    }


    public static function onAfterUpdate(Model $model)
    {
        //我的id
        $id = (string)$model['id'];
        $change_data = $model->getChangedData();
        if (array_key_exists('f_uid1', $change_data)) {
            //            $up_model = self::find($change_data['f_uid1']);

            //我的之邀信息
            $f_mch_all = empty($model['f_uid_all']) ? [] : explode(',', $model['f_uid_all']);
            //            dump($f_mch_all);exit;

            //直邀发生变化
            $max_len = 3;
            //查询我邀请的用户
            self::field('*,find_in_set(' . $id . ',f_uid_all) as f_index')->whereRaw(Db::raw('find_in_set(' . $id . ',f_uid_all)>0'))->select()
                ->each(function ($item) use ($max_len, $model, $f_mch_all) {
                    $f_index = $item['f_index'];
                    $item_f_mch_all = empty($item['f_uid_all']) ? [] : explode(',', $item['f_uid_all']);
                    $item_f_mch_all = array_slice($item_f_mch_all, 0, $f_index);
                    $last_all = array_merge($item_f_mch_all, $f_mch_all);
                    $item->setAttr('f_uid_all', implode(',', $last_all));
                    for ($i = 1; $i <= $max_len; $i++) {
                        $key = 'f_uid' . $i;
                        $item->setAttr($key, $last_all[$i - 1] ?? null);
                    }
                    $item->setAttr('f_uid1', implode(',', $last_all));
                    $item->save();
                });
        }
    }

    public static function onBeforeInsert(Model $model)
    {
        $data = $model->getData();
        $attr = [
            'req_code' => self::make_coupon_card(),
            'ip'    => app()->request->ip(),
        ];
        !array_key_exists('name', $data) && $attr['name']=rand(1000000,9999999);
        !array_key_exists('avatar', $data) && $attr['avatar'] = request()->domain() . '/assets/images/avatar.png';

        if (!empty(self::$req_user_model)) {
            $attr = array_merge($attr, self::setFuidData(self::$req_user_model));
        }

        $model->setAttrs($attr);
    }
    public static function onAfterInsert(Model $model)
    {
        //发送优惠券
        CouponModel::where(['status' => 1, 'reg_send' => 1])->select()->each(function ($item) use ($model) {
            try {
                CouponModel::getCoupon($model, ['id' => $item['id']]);
            } catch (\Exception $e) {
            }
        });

        //邀请注册
        if (!empty(self::$req_user_model)) {
            CouponModel::where(['status' => 1, 'is_req' => 1])->select()->each(function ($item) use ($model) {
                try {
                    CouponModel::getCoupon(self::$req_user_model, ['id' => $item['id']]);
                } catch (\Exception $e) {
                }
            });
        }
    }

    public static function generateQrCode($prefix, $content, $type = 'qr_code', $width = 300, $path_prefix = "")
    {
        $root_path = root_path();
        $save_path = '/uploads/' . $type . '/' . md5($path_prefix . $prefix . $content) . '.png';

        $abs_path = $root_path . $save_path;
        if (file_exists($abs_path)) {
            return $save_path;
        }
        $qrCode = new \Endroid\QrCode\QrCode($content);
        $qrCode->setSize($width);
        // Set advanced options
        $qrCode->setWriterByName('png');
        $qrCode->setMargin(-10);
        $qrCode->setEncoding('UTF-8');
        //        $qrCode->setErrorCorrectionLevel(\Endroid\QrCode\ErrorCorrectionLevel::HIGH);
        //        $qrCode->setForegroundColor(['r' => 0, 'g' => 0, 'b' => 0]);
        //        $qrCode->setBackgroundColor(['r' => 255, 'g' => 255, 'b' => 255]);
        $qrCode->setValidateResult(true);


        // Save it to a file
        $qrCode->writeFile($abs_path);
        return $save_path;
    }

    //设置层
    public static function setFuidData(UserModel $user_model)
    {
        $data = [];
        for ($i = 1; $i <= self::DEFAULT_LEVEL; $i++) {
            $field_key = 'f_uid' . $i;
            $c_i = $i - 1;
            $key = empty($c_i) ? 'id' : 'f_uid' . $c_i;
            $data[$field_key] = empty($user_model[$key]) ? null : $user_model[$key];
        }
        $data['f_uid_all'] = $user_model['id'] . (empty($user_model['f_uid_all']) ? '' : ',' . $user_model['f_uid_all']);
        return $data;
    }

    public function getHidePhoneAttr()
    {
        $phone = $this['phone'] . '';
        return substr_replace($phone, '****', 3, 4);
    }

    //vip状态
    public function getVipStateAttr()
    {
        $current_day = date('Y-m-d');
        $vip_end_day = $this['vip_end_date'];
        $state = 0;
        if ($vip_end_day >= $current_day) {
            $state = 1;
        }
        return $state;
    }

    public function modPwd(array $input_data = [])
    {
        $old_password = $input_data['old_password']??"";
        $password = $input_data['password']??"";
        if(empty($old_password)) throw new \Exception(lang('input_old_password'));
        if(empty($password)) throw new \Exception(lang('input_password'));
        if(strlen($password) < 6) throw new \Exception(lang('err_input_password_len',['len'=>6]));

        if(self::generatePwd($old_password,$this['salt'])!=$this['password'])  throw new \Exception(lang('err_old_password'));
        $this->setAttr('password',$password);
        $this->save();
    }


    /**
     * 修改用户数据
     * @param $input_data array
     * @throws
     * */
    public function modifyInfo(array $input_data = [])
    {
        if (empty($input_data)) throw new \Exception(lang('err_data'));

        $this->readonly(['money', 'integral', 'f_uid1', 'phone']);
        $this->setAttrs($input_data);

        $this->save();
    }

    public static function forgetEmail(array $input_data = [])
    {
        $email = $input_data['email']??'';
        if(empty($email))  throw new \Exception(lang('input_email'));
        if(!valid_email($email))  throw new \Exception(lang('err_input_email'));
        $user_model = self::where(['email'=>$email])->find();
        if(empty($user_model))  throw new \Exception(lang('err_email_no_reg'));
        $forget_key = uniqid("e").'.'.md5($email.rand(1000,9999));
        $user_model->setAttr('forget_key',$forget_key);
        $user_model->save();
        //发送邮件
        $url = request()->domain().'/index/forgetPwd.html?key='.$forget_key;
        EmailLogsModel::send([
            'rec_mail'=>$email,
            'body'=> lang('html_email_forget_pwd',['url'=>$url]),
            'subject' => lang('email_forget_email_subject'),
            'alt_body' => lang('email_forget_email_alt_body'),
        ]);

    }
    public static function forgetEmailModPwd(array $input_data = [])
    {
        $key = $input_data['key']??'';
        $password = $input_data['password']??'';
        if(empty($key))  throw new \Exception(lang('err_data_param',['param'=>':key']));
        if(empty($password))  throw new \Exception(lang('input_password'));
        if(strlen($password)<6)  throw new \Exception(lang('err_input_password_len',['len'=>6]));

        $user_model = self::where(['forget_key'=>$key])->find();
        if(empty($user_model))  throw new \Exception(lang('err_forgot_key_invalid'));

        $user_model->setAttr('password',$password);
        $user_model->setAttr('forget_key',null);
        $user_model->save();

    }

    /**
     * 修改用户数据
     * @param $input_data array
     * @throws
     * */
    public function modPhone(array $input_data = [])
    {
        $phone = $input_data['phone'] ?? '';
        $verify = $input_data['verify'] ?? '';
        if (empty($phone)) throw new \Exception('请输入手机号');
        if (!valid_phone($phone)) throw new \Exception('请输入正确的手机号');
        if (empty($verify)) throw new \Exception('请输入验证码');
        SmsModel::validVerify(3, $phone, $verify);
        $model = self::where([
            ['id', '<>', $this['id']],
            ['phone', '=', $phone],
        ])->find();
        if (!empty($model)) throw new \Exception('手机号已被注册');

        $this->setAttr('phone', $phone);
        $this->save();
    }


    //vip状态
    public static function upgradeVip($user_id, $day, array $data = [])
    {
        $cond_id = $data['cond_id'] ?? 0;
        $user_model = self::find($user_id);
        if (!empty($user_model)) {
            $vip_end_date = empty($user_model['vip_end_date']) ? date('Y-m-d') : $user_model['vip_end_date'];
            $vip_end_day = date('Y-m-d', strtotime("+ $day day", strtotime($vip_end_date)));
            $user_model->setAttr('vip_end_date', $vip_end_day);
            $user_model->save();
            //创建日志
            UserNoticeModel::recordLog("开通vip成功", "vip续费 $day 天", $cond_id, $user_id, 0, 4);
        }
    }


    /**
     * 页面数据
     * @param $input_data array
     * @throws
     * @return \think\Paginator
     * */
    public static function getPageData(array $input_data = [], BaseModel  $model = null)
    {
        $limit = $input_data['limit'] ?? null;
        $where = [];
        if (app()->http->getName() != 'admin') {
            $where[] = ['status', '=', 1];
        }

        $keyword = trim($input_data['keyword'] ?? '');
        !empty($keyword) && $where[] = ['name|phone|email', 'like', '%' . $keyword . '%'];

        $order_start_num = $input_data['order_start_num']??0;
        $order_end_num = $input_data['order_end_num']??0;

        if(!empty($order_start_num) && !empty($order_end_num)){
            $where[] = ['order_num','>=',$order_start_num];
            $where[] = ['order_num','<=',$order_end_num];
        }elseif(!empty($order_start_num)){
            $where[] = ['order_num','>=',$order_start_num];
        }elseif(!empty($order_end_num)){
            $where[] = ['order_num','<=',$order_end_num];
        }

        $order_start_back_num = $input_data['order_start_back_num']??0;
        $order_end_back_num = $input_data['order_end_back_num']??0;
        if(!empty($order_start_back_num) && !empty($order_end_back_num)){
            $where[] = ['order_back_num','>=',$order_start_back_num];
            $where[] = ['order_back_num','<=',$order_end_back_num];
        }elseif(!empty($order_start_back_num)){
            $where[] = ['order_back_num','>=',$order_start_back_num];
        }elseif(!empty($order_end_back_num)){
            $where[] = ['order_back_num','<=',$order_end_back_num];
        }

        return self::where($where)->order('id desc')->paginate($limit);
    }


    //保存用户
    public static function handleSaveData(array $input_data = [])
    {
        if (empty($input_data['password'])) {
            unset($input_data['password']);
        }
        if (empty($input_data['nickname'])) throw new \Exception('请输入nickname');
        //        if(empty($input_data['phone'])) throw new \Exception('请输入手机号');
        if (!empty($input_data['phone']) && !valid_phone($input_data['phone'])) throw new \Exception('请输入正确的手机号码');
        if (isset($input_data['password']) && strlen($input_data['password']) < 6) throw new \Exception('密码不得低于6位');

        if (!empty($input_data['money']) && $input_data['money'] < 0) throw new \Exception('用户余额不得低于 0');
        if (!empty($input_data['integral']) && $input_data['integral'] < 0) throw new \Exception('用户能量值不得低于 0');
        $where_check = [];
        $where_check[] = ['phone', '=', $input_data['phone']];
        if (!empty($input_data['id'])) {
            $where_check[] = ['id', '<>', $input_data['id']];
        }


        if (self::where($where_check)->find()) throw new \Exception('手机号已被注册，请更换手机号');
        (new self())->actionAdd($input_data);
    }


    public static function register(array $input_data = [])
    {
        $email = $input_data['email'] ?? '';
        $password = $input_data['password'] ?? '';
        if(empty($email)) throw new \Exception(lang('input_email'));
        if(!valid_email($email)) throw new \Exception(lang('err_input_email'));
        if(empty($password)) throw new \Exception(lang('input_password'));
        if(strlen($password) < 6) throw new \Exception(lang('err_input_password_len',['len'=>6]));
        $model_exist = UserModel::where(['email' => $email])->find();
        if(!empty($model_exist)) throw new \Exception(lang('err_email_used'));
        $model = new self();
        $model->setAttrs([
            'email'=>$email,
            'password'=>$password,
        ]);
        $model->save();
    }

    /**
     * 处理用户登录
     * @param array $input_data
     * @throws
     * @return array|self
     * */
    public static function handleLogin(array $input_data = [])
    {
        $email = $input_data['email'] ?? '';
        $password = $input_data['password'] ?? '';
        if (empty($email)) throw new \Exception(lang('input_email'));
        if (empty($password)) throw new \Exception(lang('input_password'));
        $model = self::where(["email" => $email])->find();
        if (empty($model)) throw new \Exception(lang('err_user_pwd'));
        if (self::generatePwd($password, $model['salt']) != $model['password']) throw new \Exception(lang('err_user_pwd'));


        if ($model['status'] != 1) throw new \Exception(lang('err_account_disabled'));
        //更新登录ip
        $model->ip = request()->ip();
        $model->save();
        return $model;
    }

    //获取用户信息
    public static function getUserInfo()
    {
        $user_id =  \think\facade\Session::get('user_id');
        $user = UserModel::where('id', $user_id)->find();
        $data = [
            'avatar' => $user->avatar ?? '/assets/images/avatar.png',
            'nickname' => $user->nickname ?? '',
            'phone' => $user->phone ?? '',
            'email' => $user->email ?? '',
            'sex' => $user->sex ?? 0,
            'year' => $user->year ?? '',
            'month' => $user->month ?? '',
            'day' => $user->day ?? '',
        ];
        return $data;
    }

    public function thirdBind(array $input_data = [])
    {
        $clearBind = $input_data['clearBind'] ?? 0;
        $provider = $input_data['provider'] ?? '';
        if (empty($provider)) throw new \Exception('第三方登录方式异常:provider');
        if ($provider == 'weixin') {
            $access_token = $input_data['access_token'] ?? '';
            $openid = $input_data['openid'] ?? '';
            try {
                if ($clearBind == 1) {
                    $this->setAttrs([
                        'wx_openid' => null,
                        'wx_unionid' => null,
                    ]);
                } else {
                    $update_data['wx_openid'] = $openid;
                    !empty($input_data['unionId']) && $update_data['wx_unionid'] = $input_data['unionId'];
                    $this->setAttrs($update_data);
                }
            } catch (\Exception $e) {
                throw new \Exception($e->getMessage());
            }
        }
        $this->save();
    }

    public static function handleThirdLogin(array $input_data = [])
    {
        $provider = $input_data['provider'] ?? '';
        if (empty($provider)) throw new \Exception('第三方登录方式异常:provider', 0);
        if ($provider == 'weixin') {
            $access_token = $input_data['access_token'] ?? '';
            $openid = $input_data['openid'] ?? '';
            if (empty($access_token)) throw new \Exception('第三方登录方式异常:access_token', 0);
            if (empty($openid)) throw new \Exception('第三方登录方式异常:openid', 0);
            $login_where[] = ['wx_openid', '=', $openid];
            if (!empty($input_data['unionid'])) {
                $login_where[] = ['wx_unionid', '=', $input_data['unionid']];
            }
            $model = self::whereOr($login_where)->find();

            if (empty($model)) {
                //                throw new \Exception('未关联手机号,请先进行注册',2);
                $model = new self();
                $model->setAttrs([
                    'name' => 'wx用户',
                    'wx_openid' => $openid,
                ]);
                $model->save();
            }
        } elseif ($provider == 'min_wx') { //小程序
            $code = $input_data['code'] ?? '';
            if (empty($code)) throw new \Exception('登录信息异常!');
            //code换信息
            $data = WxMin::auth2CodeSession($code);
            $openid = $data['openid'] ?? '';
            $unionid = $data['unionid'] ?? '';
            $where = [];
            if (!empty($unionid)) {
                $where[] = ['wx_unionid', '=', $unionid];
            } elseif (!empty($openid)) {
                $where[] = ['min_openid', '=', $openid];
            }
            $model = self::where($where)->find();
            if (empty($model)) {
                //                throw new \Exception('未关联手机号,请先进行注册',2);
            }
        } elseif ($provider == 'apple') {
            $apple_id = $input_data['openid'] ?? '';
            if (empty($apple_id)) throw new \Exception('第三方登录方式异常:apple_id', 0);
            $model = self::where(['apple_id' => $apple_id])->find();
            if (empty($model)) {
                //                throw new \Exception(json_encode($input_data),2);
                //                throw new \Exception('未关联手机号,请先进行注册',2);
                $model = new self();
                $model->setAttrs([
                    'name' => 'apple',
                    'apple_id' => $apple_id,
                ]);
                $model->save();
            }
        } else {
            throw new \Exception('第三方登录方式异常:provider', 0);
        }
        return $model;
    }



    /**
     * 授权绑定手机
     * @param array $data  数据
     * @throws
     * @return self
     * */
    public static function authBindphone(array $php_input)
    {

        $platform = $input_data['platform'] ?? '';
        $clientid = $input_data['clientid'] ?? '';
        $phone = $php_input['phone'] ?? '';
        $verify = $php_input['verify'] ?? '';
        //        $password = $php_input['password']??'';
        $name = $php_input['name'] ?? '';
        if (empty($phone)) throw new \Exception('请输入手机号');
        //        if(empty($name)) throw new \Exception('请输入您的昵称');
        if (empty($verify)) throw new \Exception('请输入验证码');
        //        if(empty($password)) throw new \Exception('请输入密码');
        //        if(strlen($password)<6) throw new \Exception('密码长度不得低于6位');
        $third_auth_info = $php_input['user_info'] ?? [];
        if (empty($third_auth_info)) throw new \Exception('请先进行授权');
        //更新的数据
        $update_data = [];
        if ($third_auth_info['provider'] == 'wxh5') {
            try {
                $auth_info = WechatJS::actToUserInfo($third_auth_info['h5_open_id']);


                $update_data['h5_open_id'] = $third_auth_info['h5_open_id'];
                $update_data['sex'] = $auth_info['sex'] ?? 0;
                $update_data['avatar'] = $auth_info['headimgurl'] ?? '';
                !empty($auth_info['unionid']) && $update_data['wx_unionid'] = $auth_info['unionid'] ?? '';
            } catch (\Exception $e) {
                throw new \Exception('微信信息异常~' . $e->getMessage());
            }
        } elseif ($third_auth_info['provider'] == 'weixin') {
            //            $access_token = $third_auth_info['access_token']??'';
            $openid = $third_auth_info['openId'] ?? '';

            //微信授权
            try {
                //                $auth_info = WechatOpen::actToUserInfo($access_token,$openid);

                empty($php_input['name']) && $update_data['name'] = $third_auth_info['nickName'];
                $update_data['wx_openid'] = $openid;
                $update_data['sex'] = $third_auth_info['gender'] ?? 1;
                $update_data['avatar'] = $third_auth_info['avatarUrl'] ?? '';

                !empty($third_auth_info['unionId']) && $update_data['wx_unionid'] = $third_auth_info['unionId'];
            } catch (\Exception $e) {
                throw new \Exception($e->getMessage());
            }
        } elseif ($third_auth_info['provider'] == 'min_wx') { //小程序
            $auth_data = $php_input['auth_data'] ?? [];
            $openid = $auth_data['openid'] ?? '';
            //微信授权
            try {
                empty($php_input['name']) && $update_data['name'] = $third_auth_info['nickName'];
                $update_data['min_openid'] = $openid;
                $update_data['sex'] = $third_auth_info['gender'] ?? 1;
                $update_data['avatar'] = $third_auth_info['avatarUrl'] ?? '';

                !empty($auth_data['unionid']) && $update_data['wx_unionid'] = $auth_data['unionid'];
            } catch (\Exception $e) {
                throw new \Exception($e->getMessage());
            }
            //            dump($update_data);exit;
        } elseif ($third_auth_info['provider'] == 'apple') {
            $apple_id = $third_auth_info['openId'] ?? '';
        } else {
            throw new \Exception('授权信息异常!');
        }
        SmsModel::validVerify(4, $phone, $verify);

        $model = self::where(['phone' => $phone])->find();
        if (empty($model)) {
            if (array_key_exists('h5_open_id', $third_auth_info)) {
                $model = self::where(['h5_open_id' => $third_auth_info['h5_open_id']])->find();
            }
            if ($third_auth_info['provider'] == 'weixin') {
                $model = self::where(['wx_openid' => $openid])->find();
            }
            if ($third_auth_info['provider'] == 'min_wx') {
                $model = self::where(['min_openid' => $openid])->find();
            } elseif ($third_auth_info['provider'] == 'apple') {
                $model = self::where(['apple_id' => $apple_id])->find();
            }
        }
        if (empty($model)) {
            $model = new self();
            $model->setAttr('phone', $phone);
        }

        $model->setAttrs($update_data);

        //        $model->setAttrs(array_merge($update_data,[
        //            'password' => $password,
        //        ]));

        !empty($auth_info['unionid']) && $model->setAttr('wx_unionid', $auth_info['unionid']);

        if (array_key_exists('h5_open_id', $third_auth_info)) {
            $model->setAttrs([
                'h5_open_id' => $third_auth_info['h5_open_id'],
            ]);
        }

        if ($third_auth_info['provider'] == 'weixin') {
            $model->setAttrs([
                'wx_openid' => $openid,
            ]);
        } elseif ($third_auth_info['provider'] == 'min_wx') {
            $model->setAttrs([
                'min_openid' => $openid,
            ]);
        } elseif ($third_auth_info['provider'] == 'apple') {
            $model->setAttrs([
                'apple_id' => $apple_id,
            ]);
        }


        if ($platform == 'android') {
            !empty($clientid) && $model->setAttr('clientid_android', $clientid);
        } elseif ($platform == 'ios') {
            !empty($clientid) && $model->setAttr('clientid_ios', $clientid);
        }


        $model->save();
        //        throw new \Exception($model['name']);
        //更新其它用户的授权信息
        if ($third_auth_info['provider'] == 'weixin') {
            self::update(['wx_openid' => null, 'wx_unionid' => null], [['wx_openid', '=', $openid], ['id', '<>', $model['id']], ['delete_time', '=', null]]);
        } elseif ($third_auth_info['provider'] == 'min_wx') {
            self::update(['min_openid' => null, 'wx_unionid' => null], [['min_openid', '=', $openid], ['id', '<>', $model['id']], ['delete_time', '=', null]]);
        } elseif ($third_auth_info['provider'] == 'apple') {
            self::update(['apple_id' => null], [['apple_id', '=', $apple_id], ['id', '<>', $model['id']], ['delete_time', '=', null]]);
        }


        return $model;
    }

    //积分兑换
    public function integralExchange(array $input_data = [])
    {
        $user_integral = $this['integral'];
        $user_money = $this['money'];
        $integral = intval($input_data['integral'] ?? 0);
        if (empty($integral)) throw new \Exception("请输入兑换的积分");
        if ($integral % 100 != 0) throw new \Exception("输入的积分数量必须是100的倍数");
        if ($integral > $user_integral) throw new \Exception("账户积分不足");
        list($num, $intro) = SysSettingModel::getIntegralExchangeIntro();
        if (empty($num))  throw new \Exception("兑换通道已关闭");

        try {
            Db::startTrans();
            //计算兑换现金比例
            $per = 1 / $num;
            $money = $integral * $per;
            $row_num = UserModel::where(['id' => $this['id'], 'integral' => $user_integral])->update([
                'money' => Db::raw('money+' . $money),
                'history_money' => Db::raw('history_money+' . $money),
                'integral' => Db::raw('integral-' . $integral),
            ]);

            if (empty($row_num)) throw new \Exception("操作频繁,请重新尝试");

            //增加日志
            UserLogsModel::recordData(1, $this['id'], -$integral, "积分兑换现金", [
                'm_type' => 2, 'q_money' => $user_integral, 'h_money' => $user_integral - $integral
            ]);
            //增加日志
            UserLogsModel::recordData(2, $this['id'], $money, "积分兑换获得", [
                'm_type' => 4, 'q_money' => $user_money, 'h_money' => $user_money + $money
            ]);

            Db::commit();
        } catch (\Exception $e) {
            Db::rollback();
            throw new \Exception("兑换失败,请稍后尝试");
        }
    }

    //获取直邀请人数
    public static function getDictReqNum($user_id)
    {
        if (empty($user_id)) {
            return 0;
        }
        return self::where(['f_uid1' => $user_id])->count();
    }

    public static function getDictReqList($user_id)
    {
        $list = [];
        if (!empty($user_id)) {
            //            self::where(['f_uid1'=>$user_id])->order('id desc')->limit(15)->select()->each(function($item)use(&$list){
            self::order('id desc')->limit(4)->select()->each(function ($item) use (&$list) {
                array_push($list, [
                    'id' => $item['id'],
                    'name' => $item['name'],
                    'avatar' => $item['avatar'],
                ]);
            });
        }
        return $list;
    }


    //列表统计
    public static function echarts(array $php_input)
    {
        $date_mode = $php_input['date_mode'] ?? 'day';
        $where = [];
        $group = 'op_time';
        $field = ' count(*) as count_num ';
        if ($date_mode == 'day') { //按小时计算
            $where[] = ['create_time', '>=', strtotime(date('Y-m-d'))];
            $field .= ' ,FROM_UNIXTIME(create_time,\'%H\') as op_time';
        } elseif ($date_mode == 'week') {
            $where[] = ['create_time', '>=', strtotime(date('Y-m-d')) - 7 * 84600];
            $field .= ' ,FROM_UNIXTIME(create_time,\'%Y-%m-%d\') as op_time';
        } elseif ($date_mode == 'month') {
            $field .= ' ,FROM_UNIXTIME(create_time,\'%Y-%m-%d\') as op_time';
            $where[] = ['create_time', '>=', strtotime(date('Y-m-d')) - 30 * 84600];
        } elseif ($date_mode == 'month60') {
            $field .= ' ,FROM_UNIXTIME(create_time,\'%Y-%m-%d\') as op_time';
            $where[] = ['create_time', '>=', strtotime(date('Y-m-d')) - 60 * 84600];
        } elseif ($date_mode == 'year') {
            $field .= ' ,FROM_UNIXTIME(create_time,\'%Y-%m-%d\') as op_time';
            $where[] = ['create_time', '>=', strtotime(date('Y-m-d')) - 365 * 84600];
        }
        $date_list = get_op_time($date_mode);
        $list = [];
        foreach ($date_list as $vo) {
            $list[$vo] = [
                'name' => $vo,
                'value' => 0
            ];
        }
        Db::table('users')->field($field)->where($where)
            ->group($group)->select()->each(function ($item) use (&$list, $date_list) {
                $key = $item['op_time'];
                $list[$key]['value'] = $item['count_num'];
            });

        return [array_column($list, 'name'), array_column($list, 'value')];
//        self::field($field)->where($where)->gourp($group)->select();

    }

    //冻结金额
    public function closeMoney()
    {
        return '0.00';
    }

    public function apiFullInfo()
    {
        return array_merge($this->apiNormalInfo(), [
            'order_num' => $this['order_num'],
            'order_back_num' => $this['order_back_num'],
            'status' => $this['status'],
            'status_name' => self::getPropInfo('fields_status', $this['status'], 'name'),
            'create_time' => $this['create_time'],
            'status_bool' => $this['status'] == true,

        ]);
    }


    public function apiNormalInfo()
    {
        return [
            'id' => $this['id'],
            'type' => $this['type'],
            'type_name' => self::getPropInfo('fields_type', $this['type'], 'name', 'value'),
            'name' => $this['name'],
            'avatar' => $this['avatar'],
            'phone' => $this['phone'],
            'email' => $this['email'],
            'money' => $this['money'],
            'integral' => $this['integral'],
        ];
    }

    public function linkFuid1()
    {
        return $this->belongsTo(UserModel::class, 'f_uid1');
    }

    public function linkFuid2()
    {
        return $this->belongsTo(UserModel::class, 'f_uid2');
    }
}
